package hexui.components;

import hexgame.*;
import hexui.ObservingPlayerFactory;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.net.UnknownHostException;
import java.util.Map;
import network.HexNetwork;
import network.NetworkPartialClientException;

public class GameConnectionPanel extends JPanel {
	private static final long serialVersionUID = 1L;

	HexGameRequest hexGameRequest;

	GridBagLayout gridBagLayout;
	JLabel hostNameLabel = new JLabel("Host name/IP:");
	JLabel portLabel = new JLabel("Port:");
	JLabel boardSizeLabel = new JLabel("Board size:");
	JLabel playFirstLabel = new JLabel("Do you want to play first?");
	JLabel observeLabel = new JLabel("Observe the game");
	JLabel playerLabel = new JLabel("Select Player:");
	JTextField hostName;
	JTextField port;
	JTextField boardSize;
	JCheckBox playFirst;
	JCheckBox observeGame;
	JButton submitButton;

	JComboBox<String> players;

	public GameConnectionPanel() {

		this.gridBagLayout = new GridBagLayout();
		this.setLayout(gridBagLayout);
		this.hostName = new JTextField("localhost");
		this.port = new JTextField("7600");
		this.boardSize = new JTextField("11");
		this.playFirst = new JCheckBox();
		this.observeGame = new JCheckBox();
		this.submitButton = new JButton();
		this.submitButton.setText("New Request");

		Map<String, PlayerFactory> methods = PlayMethods.getMethods();
		String[] playMethods = methods.keySet().toArray(new String[methods.size()]);

		this.players = new JComboBox<String>(playMethods);
		this.setComponents();
	}

	public void setComponents() {
		GridBagConstraints gc = new GridBagConstraints();

		gc.anchor = GridBagConstraints.NORTHWEST;
		gc.insets = new Insets(6, 10, 6, 10);
		gc.gridx = 0;
		gc.gridy = 0;
		this.add(hostNameLabel, gc);

		gc.insets = new Insets(6, 10, 6, 10);
		gc.gridx = 0;
		gc.gridy = 1;
		this.add(portLabel, gc);

		gc.gridx = 0;
		gc.gridy = 2;
		this.add(boardSizeLabel, gc);

		gc.gridx = 0;
		gc.gridy = 3;
		this.add(playFirstLabel, gc);
		
		gc.gridx = 0;
		gc.gridy = 4;
		this.add(observeLabel, gc);

		gc.insets = new Insets(6, 10, 6, 10);
		gc.gridx = 0;
		gc.gridy = 5;
		this.add(playerLabel, gc);

		
		gc.insets = new Insets(6, 10, 6, 10);
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.gridx = 1;
		gc.gridy = 0;
		this.add(hostName, gc);

		
		gc.insets = new Insets(6, 10, 6, 10);
		gc.gridx = 1;
		gc.gridy = 1;
		this.add(port, gc);

		gc.gridx = 1;
		gc.gridy = 2;
		this.add(boardSize, gc);

		gc.gridx = 1;
		gc.gridy = 3;
		this.add(playFirst, gc);
		
		gc.gridx = 1;
		gc.gridy = 4;
		this.add(observeGame, gc);

		gc.gridx = 1;
		gc.gridy = 5;
		this.add(players, gc);

		gc.insets = new Insets(15, 10, 6, 10);
		gc.gridx = 1;
		gc.gridy = 6;
		submitButton.addActionListener(new RequestListener());
		this.add(submitButton, gc);

	}
	
	class RequestListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			HexGameRequest request = this.createHexGameRequest(hostName.getText(), Integer.parseInt(port.getText()), Integer.parseInt(boardSize.getText()), playFirst.isSelected(), (String) players.getSelectedItem());
			if(observeGame.isSelected()) {
				String name = (String)players.getSelectedItem();
				request.setObserverFactory(new ObservingPlayerFactory(name));
			}
			HexGame game = new HexGame(request);

			game.startGame();
		}

		public HexGameRequest createHexGameRequest(String hostName, int port, int boardSize, boolean firstPlayer, String player) {
			HexGameRequest hexGameRequest;
			try {
				hexGameRequest = HexNetwork.connectTo(hostName, port, boardSize, firstPlayer);

				PlayerFactory factory = PlayMethods.getMethods().get(player);

				if (factory == null) {
					// TODO Unknown error occurred (Selected play method isn't
					// valid)
					return null;
				}
				
				hexGameRequest.setLocalPlayerFactory(factory);
			} catch (UnknownHostException e) {
				// TODO Invalid IP / Hostname error

				return null;
			} catch (NetworkPartialClientException e) {
				// TODO Unable to connect to Host (Connection refused or invalid
				// handshake)

				return null;
			}

			return hexGameRequest;
		}

	}
}
